import streamlit as st
import requests
import time
from datetime import datetime, date

# Flask 后端 API 地址
API_BASE_URL = "http://localhost:5000/api"

@st.cache_data(ttl=2, show_spinner=False)
def fetch_todos(refresh_trigger=None):
    """获取所有待办事项，使用缓存减少API调用
    
    Args:
        refresh_trigger: 刷新触发器，值变化时强制刷新缓存
    """
    try:
        response = requests.get(f"{API_BASE_URL}/todos")
        return response.json() if response.status_code == 200 else []
    except requests.exceptions.RequestException:
        st.error("无法连接到后端服务，请确保 Flask 服务器正在运行")
        return []

def add_todo(text, priority="中", due_date=None):
    """添加新的待办事项"""
    try:
        data = {"text": text, "priority": priority}
        if due_date:
            data["due_date"] = due_date.isoformat() if hasattr(due_date, 'isoformat') else due_date
        response = requests.post(f"{API_BASE_URL}/todos", json=data)
        return response.status_code == 201
    except requests.exceptions.RequestException:
        return False

def update_todo(todo_id, text, priority="中", due_date=None):
    """更新待办事项"""
    try:
        data = {"text": text, "priority": priority}
        if due_date:
            data["due_date"] = due_date.isoformat() if hasattr(due_date, 'isoformat') else due_date
        response = requests.put(f"{API_BASE_URL}/todos/{todo_id}/update", json=data)
        return response.status_code == 200
    except requests.exceptions.RequestException:
        return False

def delete_todo(todo_id):
    try:
        response = requests.delete(f"{API_BASE_URL}/todos/{todo_id}")
        return response.status_code == 200
    except requests.exceptions.RequestException:
        return False

def toggle_todo(todo_id):
    """切换待办事项的完成状态"""
    try:
        response = requests.put(f"{API_BASE_URL}/todos/{todo_id}")
        return response.status_code == 200
    except requests.exceptions.RequestException:
        return False

# Streamlit 页面配置 - 使用紧凑布局
st.set_page_config(
    page_title="智能Todo管理系统",
    page_icon="📋",
    layout="centered",  # 改为centered布局，更紧凑
    initial_sidebar_state="expanded"
)

# 初始化session state
if 'refresh_trigger' not in st.session_state:
    st.session_state.refresh_trigger = 0

# 自定义CSS样式 - 优化布局紧凑性和按钮美观度
st.markdown("""
<style>
.priority-high { color: #ff4444; font-weight: bold; }
.priority-medium { color: #ff8800; font-weight: bold; }
.priority-low { color: #44aa44; font-weight: bold; }
.due-soon { background-color: #fff3cd; padding: 2px 6px; border-radius: 4px; }
.overdue { background-color: #f8d7da; padding: 2px 6px; border-radius: 4px; }
.task-completed { opacity: 0.6; }
.main-header { 
    background: linear-gradient(90deg, #667eea 0%, #764ba2 100%);
    padding: 0.8rem;
    border-radius: 8px;
    color: white;
    text-align: center;
    margin-bottom: 1rem;
}
.task-card {
    background: #f8f9fa;
    padding: 0.4rem;
    border-radius: 0;
    margin-bottom: 0;
    border-left: 3px solid #667eea;
    border-bottom: 1px solid #dee2e6;
    box-shadow: none;
}

/* 优化按钮样式 - 防止换行 */
.stButton > button {
    height: 2rem;
    padding: 0.2rem 0.4rem;
    font-size: 0.75rem;
    border-radius: 4px;
    border: 1px solid #ddd;
    background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%);
    transition: all 0.2s ease;
    white-space: nowrap;
    min-width: fit-content;
}
.stButton > button:hover {
    background: linear-gradient(135deg, #e9ecef 0%, #dee2e6 100%);
    border-color: #adb5bd;
    transform: translateY(-1px);
    box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
/* 减少间距 */
.block-container {
    padding-top: 0.8rem;
    padding-bottom: 0.8rem;
}
.element-container {
    margin-bottom: 0.2rem;
}
/* 优化容器间距 */
div[data-testid="column"] {
    padding: 0.05rem;
}
/* 移除容器间距 */
.stContainer {
    padding: 0 !important;
    margin: 0 !important;
}
div[data-testid="stVerticalBlock"] > div {
    gap: 0 !important;
}
/* 减少成功消息显示时间 */
.stAlert {
    margin-bottom: 0.3rem;
}
</style>
""", unsafe_allow_html=True)

# 页面标题 - 更紧凑
st.markdown('<div class="main-header"><h2>📋 智能Todo管理系统</h2><p>高效管理您的日常任务</p></div>', unsafe_allow_html=True)

# 侧边栏 - 添加任务和过滤选项
with st.sidebar:
    st.header("📝 添加新任务")
    
    # 使用表单来避免session_state错误，优化添加任务流程
    with st.form("add_todo_form", clear_on_submit=True):
        new_todo = st.text_input("任务内容", placeholder="请输入您的待办事项...")
        
        col1, col2 = st.columns(2)
        with col1:
            priority = st.selectbox("优先级", ["高", "中", "低"], index=1)
        with col2:
            due_date = st.date_input("截止日期", value=None)
        
        submitted = st.form_submit_button("➕ 添加任务", type="primary", use_container_width=True)
    
    # 表单外处理提交结果，避免每次输入都触发刷新
    if submitted:
        if new_todo.strip():
            # 添加任务成功后，增加刷新触发器值，但不立即刷新
            if add_todo(new_todo.strip(), priority, due_date):
                st.session_state.refresh_trigger += 1
                # 使用success消息而不是立即刷新
                st.success("✅ 任务添加成功")
                # 延迟刷新，给用户看到成功消息的时间
                time.sleep(0.5)
                st.rerun()
            else:
                st.error("❌ 添加失败，请检查后端服务")
        else:
            st.warning("⚠️ 任务内容不能为空")
    
    st.markdown("---")
    
    # 过滤和搜索选项
    st.header("🔍 筛选选项")
    search_text = st.text_input("🔎 搜索任务", placeholder="输入关键词搜索...")
    filter_priority = st.multiselect("按优先级筛选", ["高", "中", "低"], default=[])
    filter_status = st.radio("任务状态", ["全部", "未完成", "已完成"], index=0)

# 主内容区域
# 获取待办事项数据 - 使用刷新触发器确保数据及时更新
todos = fetch_todos(refresh_trigger=st.session_state.refresh_trigger)

if todos:
    # 应用过滤条件
    filtered_todos = todos
    
    # 搜索过滤
    if search_text:
        filtered_todos = [todo for todo in filtered_todos if search_text.lower() in todo['text'].lower()]
    
    # 优先级过滤 - 如果没有选择任何优先级，则显示所有任务
    if filter_priority:
        filtered_todos = [todo for todo in filtered_todos if todo.get('priority', '中') in filter_priority]
    
    # 状态过滤
    if filter_status == "未完成":
        filtered_todos = [todo for todo in filtered_todos if not todo['completed']]
    elif filter_status == "已完成":
        filtered_todos = [todo for todo in filtered_todos if todo['completed']]
    
    # 统计信息 - 更紧凑的布局
    total_tasks = len(todos)
    completed_tasks = len([todo for todo in todos if todo['completed']])
    pending_tasks = total_tasks - completed_tasks
    
    # 显示统计卡片 - 使用更紧凑的布局
    col1, col2, col3, col4 = st.columns(4)
    with col1:
        st.metric("📊 总任务", total_tasks, delta=None)
    with col2:
        st.metric("✅ 已完成", completed_tasks, delta=None)
    with col3:
        st.metric("🔄 进行中", pending_tasks, delta=None)
    with col4:
        completion_rate = (completed_tasks / total_tasks * 100) if total_tasks > 0 else 0
        st.metric("📈 完成率", f"{completion_rate:.1f}%", delta=None)
    
    if filtered_todos:
        st.subheader(f"📋 任务列表 ({len(filtered_todos)} 项)")
        
        # 按优先级和状态排序
        priority_order = {"高": 0, "中": 1, "低": 2}
        filtered_todos.sort(key=lambda x: (x['completed'], priority_order.get(x.get('priority', '中'), 1)))
        
        for i, todo in enumerate(filtered_todos):
            # 创建任务卡片 - 使用更紧凑的布局
            with st.container():
                st.markdown('<div class="task-card">', unsafe_allow_html=True)
                
                col1, col2, col3, col4 = st.columns([0.8, 5.5, 1.2, 1.5])
                
                # 复选框 - 使用on_change回调而非直接重新加载
                with col1:
                    current_status = todo['completed']
                    
                    # 定义状态切换回调函数
                    def toggle_status_callback(todo_id=todo['id']):
                        if toggle_todo(todo_id):
                            st.session_state.refresh_trigger += 1
                    
                    st.checkbox("完成状态", key=f"check_{todo['id']}", 
                               value=current_status, 
                               label_visibility="hidden",
                               on_change=toggle_status_callback if st.session_state.get(f"check_{todo['id']}") != current_status else None)
                
                # 任务内容和详情 - 一行显示
                with col2:
                    # 构建一行显示的内容
                    task_parts = []
                    
                    # 任务文本
                    if todo['completed']:
                        task_parts.append(f"<span class='task-completed'>~~{todo['text']}~~</span>")
                    else:
                        task_parts.append(f"**{todo['text']}**")
                    
                    # 优先级
                    priority = todo.get('priority', '中')
                    if priority == '高':
                        priority_class = 'priority-high'
                    elif priority == '低':
                        priority_class = 'priority-low'
                    else:
                        priority_class = 'priority-medium'
                    
                    task_parts.append(f"<span class='{priority_class}'>🔥 {priority}</span>")
                    
                    # 截止日期
                    if todo.get('due_date'):
                        due_date = datetime.fromisoformat(todo['due_date']).date()
                        today = date.today()
                        days_diff = (due_date - today).days
                        
                        if days_diff < 0:
                            task_parts.append(f"<span class='overdue'>⚠️ 逾期{abs(days_diff)}天</span>")
                        elif days_diff == 0:
                            task_parts.append(f"<span class='due-soon'>📅 今天到期</span>")
                        elif days_diff <= 3:
                            task_parts.append(f"<span class='due-soon'>📅 {days_diff}天后</span>")
                        else:
                            task_parts.append(f"📅 {due_date.strftime('%m-%d')}")
                    
                    # 在一行中显示所有信息
                    st.markdown(" | ".join(task_parts), unsafe_allow_html=True)
                
                # 编辑按钮 - 使用回调函数优化性能
                with col3:
                    # 定义编辑状态切换回调函数
                    def edit_callback(todo_id=todo['id']):
                        st.session_state[f"editing_{todo_id}"] = True
                    
                    # 使用按钮点击事件触发回调
                    st.button("编辑", key=f"edit_{todo['id']}", help="编辑任务", on_click=edit_callback)
                
                # 删除按钮 - 使用回调函数优化性能
                with col4:
                    # 定义删除回调函数
                    def delete_callback(todo_id=todo['id']):
                        if delete_todo(todo_id):
                            st.session_state.refresh_trigger += 1
                    
                    # 使用按钮点击事件触发回调
                    st.button("删除", key=f"delete_{todo['id']}", help="删除任务", on_click=delete_callback)
                
                st.markdown('</div>', unsafe_allow_html=True)
                
                # 编辑模式 - 使用表单提交，避免实时刷新
                if st.session_state.get(f"editing_{todo['id']}", False):
                    with st.expander("✏️ 编辑任务", expanded=True):
                        # 使用表单组件，一次性提交所有修改
                        with st.form(key=f"edit_form_{todo['id']}"):
                            edit_text = st.text_input("任务内容", value=todo['text'], key=f"edit_text_{todo['id']}")
                            
                            col_edit1, col_edit2 = st.columns(2)
                            with col_edit1:
                                edit_priority = st.selectbox("优先级", ["高", "中", "低"], 
                                                          index=["高", "中", "低"].index(todo.get('priority', '中')),
                                                          key=f"edit_priority_{todo['id']}")
                            with col_edit2:
                                current_due = None
                                if todo.get('due_date'):
                                    current_due = datetime.fromisoformat(todo['due_date']).date()
                                edit_due_date = st.date_input("截止日期", value=current_due, key=f"edit_due_{todo['id']}")
                            
                            col_save, col_cancel = st.columns(2)
                            with col_save:
                                save_submitted = st.form_submit_button("💾 保存", type="primary")
                            with col_cancel:
                                cancel_submitted = st.form_submit_button("❌ 取消")
                        
                        # 表单外处理提交结果 - 优化刷新逻辑
                        if save_submitted:
                            if update_todo(todo['id'], edit_text, edit_priority, edit_due_date):
                                # 更新成功，关闭编辑模式并增加刷新触发器
                                st.session_state[f"editing_{todo['id']}"] = False
                                st.session_state.refresh_trigger += 1
                                # 显示成功消息
                                st.success("✅ 任务更新成功")
                                # 短暂延迟后刷新
                                time.sleep(0.5)
                                st.rerun()
                            else:
                                st.error("❌ 更新失败")
                        elif cancel_submitted:
                            # 取消编辑，只需关闭编辑模式，不需要刷新页面
                            st.session_state[f"editing_{todo['id']}"] = False
    else:
        st.info("🔍 没有找到符合条件的任务")
else:
    st.info("📋 暂无待办事项，从侧边栏添加一些任务开始吧！")

# 批量操作功能 - 提高性能
if todos and len(filtered_todos) > 1:
    with st.expander("⚡ 批量操作", expanded=False):
        st.markdown("### 批量操作多个任务")        
        # 批量标记完成/未完成
        col1, col2 = st.columns(2)
        with col1:
            if st.button("✅ 标记所有为已完成", use_container_width=True):
                success_count = 0
                for todo in filtered_todos:
                    if not todo['completed']:
                        if toggle_todo(todo['id']):
                            success_count += 1
                if success_count > 0:
                    st.session_state.refresh_trigger += 1
                    st.success(f"✅ 已将 {success_count} 个任务标记为完成")
                    time.sleep(0.5)
                    st.rerun()
        
        with col2:
            if st.button("🔄 标记所有为未完成", use_container_width=True):
                success_count = 0
                for todo in filtered_todos:
                    if todo['completed']:
                        if toggle_todo(todo['id']):
                            success_count += 1
                if success_count > 0:
                    st.session_state.refresh_trigger += 1
                    st.success(f"🔄 已将 {success_count} 个任务标记为未完成")
                    time.sleep(0.5)
                    st.rerun()

# 页面底部信息 - 更紧凑
with st.expander("💡 使用说明"):
    st.markdown("""
    - **添加任务**: 在左侧边栏填写任务信息并点击添加
    - **完成任务**: 勾选任务前的复选框
    - **编辑任务**: 点击编辑按钮修改任务内容、优先级和截止日期
    - **删除任务**: 点击删除按钮删除任务
    - **搜索过滤**: 使用左侧的搜索和筛选功能快速找到任务
    - **批量操作**: 使用批量操作功能一次处理多个任务
    """)

st.caption("🔧 技术栈: Streamlit + Flask + JSON | 📊 版本: v2.2 - 性能优化版")
st.markdown("📊 **版本:** v2.2 - 性能优化版Todo管理系统")